﻿/*
 * Copyright 2010 Edward L. Stauff.                  Contact: <EdStauff@gmail.com>.
 * 
 * This file, "ReadOnlyList.cs", is part of the "Stauffware.Common" class library.
 * "Stauffware.Common" is free software: you can redistribute it and/or 
 * modify it under the terms of the GNU Lesser Public License as published by the 
 * Free Software Foundation, either version 3 of the License, or (at your option) 
 * any later version.
 * 
 * "Stauffware.Common" is distributed in the hope that it will be useful, 
 * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 
 * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser Public License for more 
 * details.
 * 
 * You should have received a copy of the GNU Lesser Public License along with 
 * the "Stauffware.Common" sources.  If not, see <http://www.gnu.org/licenses/>.
 */

using System;
using System.Collections.Generic;

// ignore "XML comment on XXXX has cref attribute YYYY that could not be resolved"

#pragma warning disable 1574

namespace Stauffware.Common.Core
{
	/// <summary>
	/// Just like System.Collections.Generic.IList, but without the modifying methods.
	/// </summary>
	public interface IReadOnlyList<T> : IEnumerable<T>
	{
		/// <summary>
		/// <see cref="System.Collections.Generic.IList.Count"/>
		/// </summary>
		int Count { get; }

		/// <summary>
		/// <see cref="System.Collections.Generic.IList.Contains"/>
		/// </summary>
		bool Contains (T item);

		/// <summary>
		/// <see cref="System.Collections.Generic.IList.IndexOf"/>
		/// </summary>
		int IndexOf (T item);

		/// <summary>
		/// <see cref="System.Collections.Generic.IList.this"/>
		/// </summary>
		T this[int index] { get; }

		/// <summary>
		/// <see cref="System.Collections.Generic.IList.CopyTo"/>
		/// </summary>
		void CopyTo (T[] array, int arrayIndex);
	}

	/// <summary>
	/// Read-only wrapper for System.Collections.Generic.IList 
	/// that ensures read-onlyness at compile time.
	/// </summary>
	public class ReadOnlyList<T> : IReadOnlyList<T>
	{
		private readonly IList<T> innerList;

		/// <summary>
		/// constructor
		/// </summary>
		/// <param name="list">The list to be wrapped.  The list is NOT copied.</param>
		public ReadOnlyList(IList<T> list)
		{
			Require.NotNull(list);
			this.innerList = list;
		}

		/// <summary>
		/// <see cref="System.Collections.Generic.IList.IndexOf"/>
		/// </summary>
		public int IndexOf (T item) { return this.innerList.IndexOf(item); }

		/// <summary>
		/// <see cref="System.Collections.Generic.IList.this"/>
		/// </summary>
		public T this[int index] { get { return this.innerList[index]; } }

		/// <summary>
		/// <see cref="System.Collections.Generic.IList.Contains"/>
		/// </summary>
		public bool Contains (T item) { return this.innerList.Contains(item); }

		/// <summary>
		/// <see cref="System.Collections.Generic.IList.CopyTo"/>
		/// </summary>
		public void CopyTo (T[] array, int arrayIndex) { this.CopyTo(array, arrayIndex); }

		/// <summary>
		/// <see cref="System.Collections.Generic.IList.Count"/>
		/// </summary>
		public int Count { get { return this.innerList.Count; } }

		/// <summary>
		/// <see cref="System.Collections.Generic.IList.GetEnumerator"/>
		/// </summary>
		public IEnumerator<T> GetEnumerator () { return this.innerList.GetEnumerator(); }

		/// <summary>
		/// <see cref="System.Collections.IEnumerable.GetEnumerator"/>
		/// </summary>
		System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator ()
		{
			return this.innerList.GetEnumerator();
		}
	}
}
